集合大連載終於要贏來大結局了,今天會以元素讀取來收尾。讓我們開始吧!
若有寫過其他程式語言的讀者應該都相當清楚,今天如果我存取了一個超出陣列的值,常見程式語言都會送你一個錯誤,當然也有一些會直接幫你 Overflow (X) 存取一些不該存取的內容。要處理這種問題也不乏很多手段,最簡單且暴力的方法就是用 try-catch
把讀值的段落用 try
包起來,並在 catch
段落給予預設手段。
在 Kotlin 裡面,我們可以對集合 (但不限於) 使用 getOrElse()
來做存取,Kotlin 提供了一個較為簡潔的方法讓我們可以賦予 catch 段落的行為,我們直接看範例跟官方定義。
val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap.get("one")) // 常見取值手法
println(numbersMap["one"]) // 常見取值手法
//numbersMap.getValue("six") // 常見取錯值的情況,拿到 Exception
println(numbersMap["five"]) // null (使處並不會報錯,但會讓你陷入問號循環
println(numbersMap.getOrDefault("four", 10)) // 10
println(numbersMap.getOrElse("four", {10} )) // 10
這時候你可能就會很好奇了,明明都是取值,為什麼要有 getOrDefault
, getOrElse
兩種寫法呢?其實仔細觀察你可以發現 getOrElse
後面的 10
多了一個大括弧,這部分我們可以從 Kotlin 官方文件看出端倪
inline fun <K, V> Map<K, V>.getOrElse(
key: K,
defaultValue: () -> V
): V
fun <K, V> Map<out K, V>.getOrDefault(
key: K,
defaultValue: V
): V
上面擷取自官方文件,忽略掉 fun
(這部分後面提到 function 函式會再說明),兩個段落對於對映 (Map) 的後面都有 <K, V>
的敘述,這其實就是前面提過的鍵值對,K 表示鍵值,V 表示該鍵值所帶的值,有點拗口,但讀者可以想像成一面置物櫃,你有一把鑰匙 (K) 打開鎖後會得到內容物 (V)。
然後我們看到兩個段落中間兩行 key
跟 defaultValue
,前者就是你想要拿的那格置物櫃,後者就是 Kotlin 幫大家準備好放 catch
段落的部分。差別就在於,使用 getOrElse
你可以在 defaultValue
放入一個函式 (可以想像成一系列你希望作的指令集合) 只要她回傳的型別跟原本的對映相同即可,但如果使用 getOrDefault
就只能傳入該型別的一個值,沒有辦法放入函式。
println(numbersMap.getOrDefault("four", {10} ))
// Function0<java.lang.Integer>